//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension ElasticInference {
    // MARK: Enums

    public enum LocationType: String, CustomStringConvertible, Codable, _SotoSendable {
        case availabilityZone = "availability-zone"
        case availabilityZoneId = "availability-zone-id"
        case region
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AcceleratorType: AWSDecodableShape {
        ///  The name of the Elastic Inference Accelerator type.
        public let acceleratorTypeName: String?
        ///  The memory information of the Elastic Inference Accelerator type.
        public let memoryInfo: MemoryInfo?
        ///  The throughput information of the Elastic Inference Accelerator type.
        public let throughputInfo: [KeyValuePair]?

        public init(acceleratorTypeName: String? = nil, memoryInfo: MemoryInfo? = nil, throughputInfo: [KeyValuePair]? = nil) {
            self.acceleratorTypeName = acceleratorTypeName
            self.memoryInfo = memoryInfo
            self.throughputInfo = throughputInfo
        }

        private enum CodingKeys: String, CodingKey {
            case acceleratorTypeName
            case memoryInfo
            case throughputInfo
        }
    }

    public struct AcceleratorTypeOffering: AWSDecodableShape {
        ///  The name of the Elastic Inference Accelerator type.
        public let acceleratorType: String?
        ///  The location for the offering. It will return either the region, availability zone or availability zone id for the offering depending on the locationType value.
        public let location: String?
        ///  The location type for the offering. It can assume the following values: region: defines that the offering is at the regional level. availability-zone: defines that the offering is at the availability zone level. availability-zone-id: defines that the offering is at the availability zone level, defined by the availability zone id.
        public let locationType: LocationType?

        public init(acceleratorType: String? = nil, location: String? = nil, locationType: LocationType? = nil) {
            self.acceleratorType = acceleratorType
            self.location = location
            self.locationType = locationType
        }

        private enum CodingKeys: String, CodingKey {
            case acceleratorType
            case location
            case locationType
        }
    }

    public struct DescribeAcceleratorOfferingsRequest: AWSEncodableShape {
        ///  The list of accelerator types to describe.
        public let acceleratorTypes: [String]?
        ///  The location type that you want to describe accelerator type offerings for. It can assume the following values: region: will return the accelerator type offering at the regional level. availability-zone: will return the accelerator type offering at the availability zone level. availability-zone-id: will return the accelerator type offering at the availability zone level returning the availability zone id.
        public let locationType: LocationType

        public init(acceleratorTypes: [String]? = nil, locationType: LocationType) {
            self.acceleratorTypes = acceleratorTypes
            self.locationType = locationType
        }

        public func validate(name: String) throws {
            try self.acceleratorTypes?.forEach {
                try validate($0, name: "acceleratorTypes[]", parent: name, max: 256)
                try validate($0, name: "acceleratorTypes[]", parent: name, min: 1)
                try validate($0, name: "acceleratorTypes[]", parent: name, pattern: "^\\S+$")
            }
            try self.validate(self.acceleratorTypes, name: "acceleratorTypes", parent: name, max: 100)
        }

        private enum CodingKeys: String, CodingKey {
            case acceleratorTypes
            case locationType
        }
    }

    public struct DescribeAcceleratorOfferingsResponse: AWSDecodableShape {
        ///  The list of accelerator type offerings for a specific location.
        public let acceleratorTypeOfferings: [AcceleratorTypeOffering]?

        public init(acceleratorTypeOfferings: [AcceleratorTypeOffering]? = nil) {
            self.acceleratorTypeOfferings = acceleratorTypeOfferings
        }

        private enum CodingKeys: String, CodingKey {
            case acceleratorTypeOfferings
        }
    }

    public struct DescribeAcceleratorTypesRequest: AWSEncodableShape {
        public init() {}
    }

    public struct DescribeAcceleratorTypesResponse: AWSDecodableShape {
        ///  The available accelerator types.
        public let acceleratorTypes: [AcceleratorType]?

        public init(acceleratorTypes: [AcceleratorType]? = nil) {
            self.acceleratorTypes = acceleratorTypes
        }

        private enum CodingKeys: String, CodingKey {
            case acceleratorTypes
        }
    }

    public struct DescribeAcceleratorsRequest: AWSEncodableShape {
        ///  The IDs of the accelerators to describe.
        public let acceleratorIds: [String]?
        ///  One or more filters. Filter names and values are case-sensitive. Valid filter names are: accelerator-types: can provide a list of accelerator type names to filter for. instance-id: can provide a list of EC2 instance ids to filter for.
        public let filters: [Filter]?
        ///  The total number of items to return in the command's output. If the total number of items available is more than the value specified, a NextToken is provided in the command's output. To resume pagination, provide the NextToken value in the starting-token argument of a subsequent command. Do not use the NextToken response element directly outside of the AWS CLI.
        public let maxResults: Int?
        ///  A token to specify where to start paginating. This is the NextToken from a previously truncated response.
        public let nextToken: String?

        public init(acceleratorIds: [String]? = nil, filters: [Filter]? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.acceleratorIds = acceleratorIds
            self.filters = filters
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.acceleratorIds?.forEach {
                try validate($0, name: "acceleratorIds[]", parent: name, max: 256)
                try validate($0, name: "acceleratorIds[]", parent: name, min: 1)
                try validate($0, name: "acceleratorIds[]", parent: name, pattern: "^eia-[0-9a-f]+$")
            }
            try self.validate(self.acceleratorIds, name: "acceleratorIds", parent: name, max: 1000)
            try self.filters?.forEach {
                try $0.validate(name: "\(name).filters[]")
            }
            try self.validate(self.filters, name: "filters", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 0)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[A-Za-z0-9+/]+={0,2}$")
        }

        private enum CodingKeys: String, CodingKey {
            case acceleratorIds
            case filters
            case maxResults
            case nextToken
        }
    }

    public struct DescribeAcceleratorsResponse: AWSDecodableShape {
        ///  The details of the Elastic Inference Accelerators.
        public let acceleratorSet: [ElasticInferenceAccelerator]?
        ///  A token to specify where to start paginating. This is the NextToken from a previously truncated response.
        public let nextToken: String?

        public init(acceleratorSet: [ElasticInferenceAccelerator]? = nil, nextToken: String? = nil) {
            self.acceleratorSet = acceleratorSet
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case acceleratorSet
            case nextToken
        }
    }

    public struct ElasticInferenceAccelerator: AWSDecodableShape {
        ///  The health of the Elastic Inference Accelerator.
        public let acceleratorHealth: ElasticInferenceAcceleratorHealth?
        ///  The ID of the Elastic Inference Accelerator.
        public let acceleratorId: String?
        ///  The type of the Elastic Inference Accelerator.
        public let acceleratorType: String?
        ///  The ARN of the resource that the Elastic Inference Accelerator is attached to.
        public let attachedResource: String?
        ///  The availability zone where the Elastic Inference Accelerator is present.
        public let availabilityZone: String?

        public init(acceleratorHealth: ElasticInferenceAcceleratorHealth? = nil, acceleratorId: String? = nil, acceleratorType: String? = nil, attachedResource: String? = nil, availabilityZone: String? = nil) {
            self.acceleratorHealth = acceleratorHealth
            self.acceleratorId = acceleratorId
            self.acceleratorType = acceleratorType
            self.attachedResource = attachedResource
            self.availabilityZone = availabilityZone
        }

        private enum CodingKeys: String, CodingKey {
            case acceleratorHealth
            case acceleratorId
            case acceleratorType
            case attachedResource
            case availabilityZone
        }
    }

    public struct ElasticInferenceAcceleratorHealth: AWSDecodableShape {
        ///  The health status of the Elastic Inference Accelerator.
        public let status: String?

        public init(status: String? = nil) {
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case status
        }
    }

    public struct Filter: AWSEncodableShape {
        ///  The filter name for the Elastic Inference Accelerator list. It can assume the following values: accelerator-type: the type of Elastic Inference Accelerator to filter for. instance-id: an EC2 instance id to filter for.
        public let name: String?
        ///  The values for the filter of the Elastic Inference Accelerator list.
        public let values: [String]?

        public init(name: String? = nil, values: [String]? = nil) {
            self.name = name
            self.values = values
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^\\S+$")
            try self.values?.forEach {
                try validate($0, name: "values[]", parent: name, max: 500_000)
                try validate($0, name: "values[]", parent: name, pattern: "^.*$")
            }
            try self.validate(self.values, name: "values", parent: name, max: 100)
        }

        private enum CodingKeys: String, CodingKey {
            case name
            case values
        }
    }

    public struct KeyValuePair: AWSDecodableShape {
        ///  The throughput value of the Elastic Inference Accelerator type. It can assume the following values: TFLOPS16bit: the throughput expressed in 16bit TeraFLOPS. TFLOPS32bit: the throughput expressed in 32bit TeraFLOPS.
        public let key: String?
        ///  The throughput value of the Elastic Inference Accelerator type.
        public let value: Int?

        public init(key: String? = nil, value: Int? = nil) {
            self.key = key
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case key
            case value
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn"))
        ]

        ///  The ARN of the Elastic Inference Accelerator to list the tags for.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws\\S*:elastic-inference:\\S+:\\d{12}:elastic-inference-accelerator/eia-[0-9a-f]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResult: AWSDecodableShape {
        ///  The tags of the Elastic Inference Accelerator.
        public let tags: [String: String]?

        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct MemoryInfo: AWSDecodableShape {
        ///  The size in mebibytes of the Elastic Inference Accelerator type.
        public let sizeInMiB: Int?

        public init(sizeInMiB: Int? = nil) {
            self.sizeInMiB = sizeInMiB
        }

        private enum CodingKeys: String, CodingKey {
            case sizeInMiB
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn"))
        ]

        ///  The ARN of the Elastic Inference Accelerator to tag.
        public let resourceArn: String
        ///  The tags to add to the Elastic Inference Accelerator.
        public let tags: [String: String]

        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws\\S*:elastic-inference:\\S+:\\d{12}:elastic-inference-accelerator/eia-[0-9a-f]+$")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^\\S$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct TagResourceResult: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn")),
            AWSMemberEncoding(label: "tagKeys", location: .querystring("tagKeys"))
        ]

        ///  The ARN of the Elastic Inference Accelerator to untag.
        public let resourceArn: String
        ///  The list of tags to remove from the Elastic Inference Accelerator.
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws\\S*:elastic-inference:\\S+:\\d{12}:elastic-inference-accelerator/eia-[0-9a-f]+$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^\\S$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResult: AWSDecodableShape {
        public init() {}
    }
}

// MARK: - Errors

/// Error enum for ElasticInference
public struct ElasticInferenceErrorType: AWSErrorType {
    enum Code: String {
        case badRequestException = "BadRequestException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize ElasticInference
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    ///  Raised when a malformed input has been provided to the API.
    public static var badRequestException: Self { .init(.badRequestException) }
    ///  Raised when an unexpected error occurred during request processing.
    public static var internalServerException: Self { .init(.internalServerException) }
    ///  Raised when the requested resource cannot be found.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
}

extension ElasticInferenceErrorType: Equatable {
    public static func == (lhs: ElasticInferenceErrorType, rhs: ElasticInferenceErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension ElasticInferenceErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
